package com.atguigu.juc.future;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Description: 比价案例测试单线程和多线程效率差距
 * @author： yeswater
 * @create： 2024/5/29
 */

public class CompletableFutureMallDemo {
	
	static List<NetMall> list = Arrays.asList(
			new NetMall("jd"),
			new NetMall("taobao"),
			new NetMall("pdd"),
			new NetMall("tmall"),
			new NetMall("dangdang"));
	
	/**
	 * 串行
	 */
	public static List<String> getPrice(List<NetMall> list, String productName) {
		return list.stream()
				       .map(netMall -> String.format("《" + productName + "》" + " in %s price is %.2f",
						       netMall.getNetMallName(),
						       netMall.calcPrice(productName)))
				       .collect(Collectors.toList());
	}
	
	/**
	 * 异步多线程并发
	 */
	public static List<String> getPriceByCompletableFuture(List<NetMall> list, String productName) {
		return list.stream()
				       .map(netMall -> CompletableFuture.supplyAsync(() ->
						                                                     String.format("《" + productName + "》" + " in %s price is %.2f",
								                                                     netMall.getNetMallName(),
								                                                     netMall.calcPrice(productName))
				       ))
				       .collect(Collectors.toList())
				       .stream()
				       .map(future -> future.join())
				       .collect(Collectors.toList());
		
	}
	
	/**
	 * 《mysql》 in jd price is 110.40
	 * 《mysql》 in taobao price is 110.39
	 * 《mysql》 in pdd price is 110.48
	 * 《mysql》 in tmall price is 109.85
	 * 《mysql》 in dangdang price is 109.91
	 * ------costTime: 5058 毫秒
	 * ======== ========
	 * 《mysql》 in jd price is 109.33
	 * 《mysql》 in taobao price is 110.74
	 * 《mysql》 in pdd price is 109.24
	 * 《mysql》 in tmall price is 110.04
	 * 《mysql》 in dangdang price is 110.65
	 * ------costTime: 1003 毫秒
	 * 
	 * 数据量越大 对比越明显
	 */
	public static void main(String[] args) {
		/**
		 * 采用step by setp方式查询
		 */
		long StartTime = System.currentTimeMillis();
		List<String> list1 = getPrice(list, "mysql");
		for (String element : list1) {
			System.out.println(element);
		}
		long endTime = System.currentTimeMillis();
		System.out.println("------costTime: " + (endTime - StartTime) + " 毫秒");
		
		System.out.println("======== ========");
		
		/**
		 * 采用 all in三个异步线程方式查询
		 */
		long StartTime2 = System.currentTimeMillis();
		List<String> list2 = getPriceByCompletableFuture(list, "mysql");
		for (String element : list2) {
			System.out.println(element);
		}
		long endTime2 = System.currentTimeMillis();
		System.out.println("------costTime: " + (endTime2 - StartTime2) + " 毫秒");
	}
	
	@Data
	@AllArgsConstructor
	@NoArgsConstructor
	private static class NetMall {
		private String netMallName;
		
		public double calcPrice(String productName) {
			try {
				TimeUnit.SECONDS.sleep(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			return ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0);
		}
	}
	
}
